package org.ndky.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.ndky.remoteService.ProviderServiceRM;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class HelloController {

    @Resource(name="abc")
    private RestTemplate restTemplate;

    @Autowired
    ProviderServiceRM providerServiceRM;

    @SentinelResource(value="hello", blockHandler = "helloLimit")
    @GetMapping("/consumer/hello")
    public String hello() {
//        String providerBack = restTemplate.getForObject("http://service-provider/provider/hello", String.class);
//        String providerBack = restTemplate.getForObject("http://localhost:8081/provider/hello", String.class);
//        String providerBack = providerServiceRM.hello();
        String providerBack = "self";
        return "consumer is here. " + "get Msg from " + providerBack;
    }

    public String helloLimit(BlockException ex) {
        return "{\"code\":\"500\",\"msg\": \"" + "服务流量控制处理\"}" + " : " + ex.getMessage();
    }

    @SentinelResource(value="responseSlow", fallback = "responseSlowFB")
    @GetMapping("/consumer/responseSlow")
    public String responseSlow() {
        int sleepCount = (int)(1+Math.random()*1000);
        try {
            Thread.sleep(sleepCount);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "consumer is here. " + "get Msg from responseSlow!!!: " + sleepCount + " ms";
    }

    public String responseSlowFB(Throwable throwable) {
        return "{\"code\":\"500\",\"msg\": \"" + "服务熔断控制处理：慢调用\"}" + " : " + throwable.getMessage();

    }

    @SentinelResource(value="responseException", fallback = "responseExceptionFB")
    @GetMapping("/consumer/responseException")
    public String responseException() {
        int randValue = (int)(1+Math.random()*1000);
        if (0 == randValue%2) {
            throw new RuntimeException("熔断异常，随机值为"+ randValue);
        } else {
            return "consumer is here. " + "get Msg from responseException!!!: " + randValue;
        }

//
    }

    public String responseExceptionFB(Throwable throwable) {
        //进入此函数存在两种情况：1. 函数抛出异常 2. 熔断规则满足
        //目前发现：如果是sentinel 异常规则进入，则throwable.getMessage() 为null
        return "{\"code\":\"500\",\"msg\": \"" + "服务熔断控制处理：异常\"}"
                + " : " + throwable.getMessage() + ". " + throwable.getCause();

    }


    @GetMapping("/consumer/helloWithReqParam")
    public String helloWithReqParam(String name, int age) {
        return "name: " + name + ", age: " + age;
    }

    @PostMapping("/consumer/helloWithReqBody")
    public String helloWithReqBody(@RequestBody String name, Integer age) {
        System.out.println("name: " + name + ", age: " + age);
      return "name: " + name + ", age: " + age;
    }
}
